/*
 * X1830 cpm definitions
 *
 * Copyright (c) 2017 Ingenic Semiconductor Co.,Ltd
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#ifndef __X1830_H__
#define __X1830_H__

#define	OST_BASE				0xb2000000

/* AHB0 BUS Devices */
#define DDRC_BASE				0xb34f0000

/* AHB2 BUS Devices */
#define SFC_BASE				0xb3440000
#define MSC0_BASE				0xb3450000
#define MSC1_BASE				0xb3460000
#define ETHC_BASE				0xb34b0000
#define EFUSE_BASE				0xb3540000

/* APB BUS Devices */
#define	CPM_BASE				0xb0000000
#define	GPIO_BASE				0xb0010000
#define	UART0_BASE				0xb0030000
#define	UART1_BASE				0xb0031000
#define	WDT_BASE				0xb0002000

/*************************************************************************
 * CPM (Clock reset and Power control Management)
 *************************************************************************/
#define CPM_CPCCR				0x00 /* Clock control register		*/
#define CPM_CPCSR				0xd4 /* Clock Status register		*/
#define CPM_CPPCR				0x0c /* PLL control register 		*/
#define CPM_CPAPCR				0x10 /* APLL control Register		*/
#define CPM_CPMPCR				0x14 /* MPLL control Register		*/
#define CPM_CPEPCR				0x58 /* EPLL control Register		*/
#define CPM_CPVPCR				0xe0 /* VPLL control Register		*/
#define CPM_DDRCDR				0x2c /* DDR clock divider register	*/
#define CPM_MACCDR				0x54 /* MAC clock divider register	*/
#define CPM_MSC0CDR				0x68 /* MSC0 clock divider register	*/
#define CPM_MSC1CDR				0xa4 /* MSC1 clock divider register	*/
#define CPM_SSICDR				0x74 /* SSI clock divider register	*/
#define CPM_DRCG				0xd0
#define CPM_MPHYC				0xe8

#define CPM_LCR					0x04
#define CPM_CLKGR0				0x20 /* Clock Gate Register0 */
#define CPM_CLKGR1				0x28 /* Clock Gate Register1 */
#define CPM_OPCR				0x24 /* Oscillator and Power Control Register */

/* DDR clock divider register */
#define CPM_DDRCDR_DCS_BIT		30
#define CPM_DDRCDR_DCS_MASK		(3 << CPM_DDRCDR_DCS_BIT)
#define CPM_DDRCDR_DCS_STOP		(0x0 << CPM_DDRCDR_DCS_BIT)
#define CPM_DDRCDR_DCS_SCLKA	(0x1 << CPM_DDRCDR_DCS_BIT)
#define CPM_DDRCDR_DCS_MPLL		(0x2 << CPM_DDRCDR_DCS_BIT)
#define CPM_DDRCDR_CE			(1 << 29)
#define CPM_DDRCDR_DDR_BUSY		(1 << 28)
#define CPM_DDRCDR_DDR_STOP		(1 << 27)
#define CPM_DDRCDR_GATE_EN		(1 << 26)
#define CPM_DDRCDR_DDRDIV_BIT	0
#define CPM_DDRCDR_DDRDIV_MASK	(0xf << CPM_DDRCDR_DDRDIV_BIT)

/* MAC clock divider register */
#define CPM_MACCDR_MACPCS_BIT	30
#define CPM_MACCDR_MACPCS_MASK	(3 << CPM_MACCDR_MACPCS_BIT)
#define CPM_MACCDR_MACPCS_SCLKA	(0x0 << CPM_MACCDR_MACPCS_BIT)
#define CPM_MACCDR_MACPCS_MPLL	(0x1 << CPM_MACCDR_MACPCS_BIT)
#define CPM_MACCDR_MACPCS_VPLL	(0x2 << CPM_MACCDR_MACPCS_BIT)
#define CPM_MACCDR_MACPCS_EPLL	(0x3 << CPM_MACCDR_MACPCS_BIT)
#define CPM_MACCDR_CE			(1 << 29)
#define CPM_MACCDR_MAC_BUSY		(1 << 28)
#define CPM_MACCDR_MAC_STOP		(1 << 27)
#define CPM_MACCDR_MACDIV_BIT	0
#define CPM_MACCDR_MACDIV_MASK	(0xff << CPM_MACCDR_MACDIV_BIT)

/* MSC clock divider register */
#define CPM_MSCCDR_MPCS_BIT		30
#define CPM_MSCCDR_MPCS_MASK	(3 << CPM_MSCCDR_MPCS_BIT)
#define CPM_MSCCDR_MPCS_SCLKA	(0x0 << CPM_MSCCDR_MPCS_BIT)
#define CPM_MSCCDR_MPCS_MPLL	(0x1 << CPM_MSCCDR_MPCS_BIT)
#define CPM_MSCCDR_MPCS_VPLL	(0x2 << CPM_MSCCDR_MPCS_BIT)
#define CPM_MSCCDR_MPCS_EPLL	(0x3 << CPM_MSCCDR_MPCS_BIT)
#define CPM_MSCCDR_CE			(1 << 29)
#define CPM_MSCCDR_MSC_BUSY		(1 << 28)
#define CPM_MSCCDR_MSC_STOP		(1 << 27)
#define CPM_MSCCDR_MSC_CLK0_SEL	(1 << 15)
#define CPM_MSCCDR_MSCDIV_BIT	0
#define CPM_MSCCDR_MSCDIV_MASK	(0xff << CPM_MSCCDR_MSCDIV_BIT)

/* SSI clock divider register */
#define CPM_SSICDR_SPCS_BIT		30
#define CPM_SSICDR_SPCS_MASK	(3 << CPM_SSICDR_SPCS_BIT)
#define CPM_SSICDR_SPCS_SCLKA	(0x0 << CPM_SSICDR_SPCS_BIT)
#define CPM_SSICDR_SPCS_MPLL	(0x1 << CPM_SSICDR_SPCS_BIT)
#define CPM_SSICDR_SPCS_VPLL	(0x2 << CPM_SSICDR_SPCS_BIT)
#define CPM_SSICDR_SPCS_EPLL	(0x3 << CPM_SSICDR_SPCS_BIT)
#define CPM_SSICDR_SCS_BIT		29
#define CPM_SSICDR_SCS_MASK		(1 << CPM_SSICDR_SCS_BIT)
#define CPM_SSICDR_SCS_EXCLK	(0x0 << CPM_SSICDR_SCS_BIT)
#define CPM_SSICDR_SCS_PLL_DIV2	(0x1 << CPM_SSICDR_SCS_BIT)
#define CPM_SSICDR_CE			(1 << 28)
#define CPM_SSICDR_SSI_BUSY		(1 << 27)
#define CPM_SSICDR_SSI_STOP		(1 << 26)
#define CPM_SSICDR_SSIDIV_BIT	0
#define CPM_SSICDR_SSIDIV_MASK	(0xff << CPM_SSICDR_SSIDIV_BIT)

/* Low Power Control Register */
#define CPM_LCR_LPM_BIT			0
#define CPM_LCR_LPM_MASK		(0x3 << CPM_LCR_LPM_BIT)
#define CPM_LCR_LPM_IDLE		(0x0 << CPM_LCR_LPM_BIT)
#define CPM_LCR_LPM_SLEEP		(0x1 << CPM_LCR_LPM_BIT)

/* Clock Gate Register0 */
#define CPM_CLKGR0_DDR			(1 << 31)
#define CPM_CLKGR0_TCU			(1 << 30)
#define CPM_CLKGR0_RTC			(1 << 29)
#define CPM_CLKGR0_DES			(1 << 28)
#define CPM_CLKGR0_CSI			(1 << 25)
#define CPM_CLKGR0_LCD			(1 << 24)
#define CPM_CLKGR0_ISP			(1 << 23)
#define CPM_CLKGR0_H1ARB		(1 << 22)
#define CPM_CLKGR0_PDMA			(1 << 21)
#define CPM_CLKGR0_SFC			(1 << 20)
#define CPM_CLKGR0_SSI1			(1 << 19)
#define CPM_CLKGR0_UART1		(1 << 15)
#define CPM_CLKGR0_UART0		(1 << 14)
#define CPM_CLKGR0_SADC			(1 << 13)
#define CPM_CLKGR0_DMIC			(1 << 12)
#define CPM_CLKGR0_AIC			(1 << 11)
#define CPM_CLKGR0_I2C2			(1 << 8)
#define CPM_CLKGR0_I2C1			(1 << 8)
#define CPM_CLKGR0_I2C0			(1 << 7)
#define CPM_CLKGR0_SSI0			(1 << 6)
#define CPM_CLKGR0_MSC1			(1 << 5)
#define CPM_CLKGR0_MSC0			(1 << 4)
#define CPM_CLKGR0_OTG			(1 << 3)
#define CPM_CLKGR0_EFUSE		(1 << 1)

/* Clock Gate Register1 */
#define CPM_CLKGR1_CPU			(1 << 15)
#define CPM_CLKGR1_APB0			(1 << 14)
#define CPM_CLKGR1_RADIX		(1 << 12)
#define CPM_CLKGR1_OST			(1 << 11)
#define CPM_CLKGR1_AHB0			(1 << 10)
#define CPM_CLKGR1_LDC			(1 << 9)
#define CPM_CLKGR1_AHB1			(1 << 6)
#define CPM_CLKGR1_AES			(1 << 5)
#define CPM_CLKGR1_GMAC			(1 << 4)
#define CPM_CLKGR1_NCU			(1 << 3)
#define CPM_CLKGR1_IPU			(1 << 2)
#define CPM_CLKGR1_DTRNG		(1 << 1)
#define CPM_CLKGR1_HELIX		(1 << 0)

/* Oscillator and Power Control Register */
#define CPM_OPCR_IDLE_DIS		(1 << 31)
#define CPM_OPCR_MASK_INT		(1 << 30)
#define CPM_OPCR_GATE_SCLKA_BUS	(1 << 28)
#define CPM_OPCR_REQ_MODE		(1 << 24)
#define CPM_OPCR_GATE_USBPHYCLK	(1 << 23)
#define CPM_OPCR_DISABLE_MUX	(1 << 22)
#define CPM_OPCR_O1ST_BIT		8
#define CPM_OPCR_O1ST_MASK		(0xff << CPM_OPCR_O1ST_BIT)
#define CPM_OPCR_SPENDN0		(1 << 7)
#define CPM_OPCR_SPENDN1		(1 << 6)
#define CPM_OPCR_O1SE			(1 << 4) /* */
#define CPM_OPCR_ERCS			(1 << 2) /* 0: select EXCLK/512 clock, 1: RTCLK clock */
#define CPM_OPCR_BUS_MODE		(1 << 1)

//n = 0,1,2,3
#define GPIO_PXPIN(n)			(0x000 + (n) * 0x1000) /* PIN Level Register */
#define GPIO_PXINT(n)			(0x010 + (n) * 0x1000) /* Port Interrupt Register */
#define GPIO_PXINTS(n)			(0x014 + (n) * 0x1000) /* Port Interrupt Set Register */
#define GPIO_PXINTC(n)			(0x018 + (n) * 0x1000) /* Port Interrupt Clear Register */
#define GPIO_PXMASK(n)			(0x020 + (n) * 0x1000) /* Port Interrupt Mask Register */
#define GPIO_PXMASKS(n)			(0x024 + (n) * 0x1000) /* Port Interrupt Mask Set Reg */
#define GPIO_PXMASKC(n)			(0x028 + (n) * 0x1000) /* Port Interrupt Mask Clear Reg */
#define GPIO_PXPAT1(n)			(0x030 + (n) * 0x1000) /* Port Pattern 1 Register */
#define GPIO_PXPAT1S(n)			(0x034 + (n) * 0x1000) /* Port Pattern 1 Set Reg. */
#define GPIO_PXPAT1C(n)			(0x038 + (n) * 0x1000) /* Port Pattern 1 Clear Reg. */
#define GPIO_PXPAT0(n)			(0x040 + (n) * 0x1000) /* Port Pattern 0 Register */
#define GPIO_PXPAT0S(n)			(0x044 + (n) * 0x1000) /* Port Pattern 0 Set Register */
#define GPIO_PXPAT0C(n)			(0x048 + (n) * 0x1000) /* Port Pattern 0 Clear Register */
#define GPIO_PXFLG(n)			(0x050 + (n) * 0x1000) /* Port Flag Register */
#define GPIO_PXFLGC(n)			(0x058 + (n) * 0x1000) /* Port Flag Clear Register */
#define GPIO_PXPEL(n)			(0x110 + (n) * 0x1000) /* Port Pull Register */
#define GPIO_PXPELS(n)			(0x114 + (n) * 0x1000) /* Port Pull Set Register */
#define GPIO_PXPELC(n)			(0x118 + (n) * 0x1000) /* Port Pull Clear Register */
#define GPIO_PXPEH(n)			(0x120 + (n) * 0x1000) /* Port Pull Register */
#define GPIO_PXPEHS(n)			(0x124 + (n) * 0x1000) /* Port Pull Set Register */
#define GPIO_PXPEHC(n)			(0x128 + (n) * 0x1000) /* Port Pull Clear Register */

#define GPIO_PA(n) 				(0*32 + n)
#define GPIO_PB(n) 				(1*32 + n)
#define GPIO_PC(n) 				(2*32 + n)
#define GPIO_PD(n) 				(3*32 + n)

/**
 * Basic configuration(SOC, Cache, UART, DDR).
 */
#define CONFIG_SYS_APLL_FREQ		1500000000
#define CONFIG_SYS_APLL_MNOD		((249 << 20) | (3 << 14) | (1 << 11) | (1 << 5))
#define CONFIG_SYS_MPLL_FREQ		1200000000
#define CONFIG_SYS_MPLL_MNOD		((149 << 20) | (2 << 14) | (1 << 11) | (1<<5))

#define CONFIG_SYS_CPU_FREQ			CONFIG_SYS_APLL_FREQ
#define CONFIG_SYS_MEM_FREQ			(CONFIG_SYS_MPLL_FREQ / 2)

#define CONFIG_DDR2_M14D1G1664A	/*DDR2 128M param file*/

#define CONFIG_SPL_CORE_VOLTAGE			1275
#define CONFIG_SPL_CORE_VOLTAGE_RATIO	22/37

#ifndef __ASSEMBLY__

#include <asm/io.h>

static inline int gpio_get_value(unsigned gpio)
{
	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
	unsigned port = gpio / 32;
	unsigned pin = gpio % 32;

	return !!(readl(gpio_regs + GPIO_PXPIN(port)) & (1 << pin));
}

static inline void gpio_port_set(int port, int pin, int value)
{
	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;

	if (value)
		writel(1 << pin, gpio_regs + GPIO_PXPAT0S(port));
	else
		writel(1 << pin, gpio_regs + GPIO_PXPAT0C(port));
}

static inline void gpio_port_direction_input(int port, int pin)
{
	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;

	writel(1 << pin, gpio_regs + GPIO_PXINTC(port));
	writel(1 << pin, gpio_regs + GPIO_PXMASKS(port));
	writel(1 << pin, gpio_regs + GPIO_PXPAT1S(port));
}

static inline void gpio_port_direction_output(int port, int pin, int value)
{
	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;

	writel(1 << pin, gpio_regs + GPIO_PXINTC(port));
	writel(1 << pin, gpio_regs + GPIO_PXMASKS(port));
	writel(1 << pin, gpio_regs + GPIO_PXPAT1C(port));

	gpio_port_set(port, pin, value);
}

static inline void gpio_direction_input(int gpio)
{
	int port = gpio / 32;
	int pin = gpio % 32;

	gpio_port_direction_input(port, pin);
}

static inline void gpio_direction_output(int gpio, int value)
{
	int port = gpio / 32;
	int pin = gpio % 32;

	gpio_port_direction_output(port, pin, value);
}

#endif /* __ASSEMBLY__ */

#endif /* __X1830_H__ */
